import React, { useEffect } from 'react';
import {fabric} from 'fabric';
import { useMemoizedFn, useReactive, useSize, useDebounceFn, useCreation } from 'ahooks';
import { SideBar, DrawerBox, UploadBox } from "@/components";
import { getScreen } from "@/utils";
import { motion } from 'framer-motion';
import { AnimatePresence } from 'motion/react';


let canvas = null;

let jsonData = {"version":"5.4.2","objects":[{"type":"image","version":"5.4.2","originX":"left","originY":"top","left":0,"top":0,"width":200,"height":200,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"cropX":0,"cropY":0,"src":"http://127.0.0.1:8080/food.png","crossOrigin":null,"filters":[]},{"type":"image","version":"5.4.2","originX":"left","originY":"top","left":0,"top":0,"width":200,"height":200,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"cropX":0,"cropY":0,"src":"http://127.0.0.1:8080/yay.jpg","crossOrigin":null,"filters":[]},{"type":"i-text","version":"5.4.2","originX":"left","originY":"top","left":0,"top":0,"width":120,"height":45.2,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"fontFamily":"Times New Roman","fontWeight":"normal","fontSize":40,"text":"雷猴啊","underline":false,"overline":false,"linethrough":false,"textAlign":"left","fontStyle":"normal","lineHeight":1.16,"textBackgroundColor":"","charSpacing":0,"styles":[],"direction":"ltr","path":null,"pathStartOffset":0,"pathSide":"left","pathAlign":"baseline"}],"background":"rgba(0,0,255,0.3)"};
// "overlayImage":{"type":"image","version":"5.4.2","originX":"left","originY":"top","left":0,"top":0,"width":1920,"height":1080,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":0.5,"scaleY":0.5,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"cropX":0,"cropY":0,"src":"http://127.0.0.1:8080/food.png","crossOrigin":null,"filters":[]}
const canvasScreen = {
    width: 965,
    height: 540,
};
console.log(jsonData);

function generateUUID() {
    var d = new Date().getTime(); //Timestamp
    var d2 = (performance && performance.now && (performance.now()*1000)) || 0; //Time in microseconds since page-load or 0 if unsupported
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16; //random number between 0 and 16
        if(d > 0) { //Use timestamp until depleted
            r = (d + r)%16 | 0;
            d = Math.floor(d/16);
        } else { //Use microseconds since page-load if supported
            r = (d2 + r)%16 | 0;
            d2 = Math.floor(d2/16);
        }
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}


const CanvasBox = () => {
    const states = useReactive({
        jsonData: {},
        realScreen: {
            width: 0,
            height: 0,
            top: 0, 
            left: 0,
        },
        zoom: 1,
        footerHeight: 100,
        isOpenDrawer: false
    })
    const constVars = useCreation(() => ({
        prevZoom: states.zoom
    }), [])

    const size = useSize(document.querySelector('body'));

    useEffect(() => {
        destoryCanvas();
    }, [])

    useEffect(() => {
        initScreen()
    }, [states.realScreen])

    useEffect(() => {
        initSize();
    }, [size, states.footerHeight])
    
    const destoryCanvas = useMemoizedFn(() => {
        if(!canvas) return;
        canvas.dispose();
        canvas = null;
    })

    const { run: initSize  } = useDebounceFn(
        () => {
            const screen = {
                width: window.innerWidth,
                height: window.innerHeight - states.footerHeight,
            };
            const realScreen = getScreen({canvasScreen, screen});
            const { zoom, ...other } = realScreen;
            console.log(zoom, other);
            states.realScreen = other;
            constVars.prevZoom = states.zoom;
            states.zoom = zoom;
        },
        {
          wait: 500,
        },
      );
    
    const initScreen = useMemoizedFn(() => {
        jsonData.objects.forEach(item => {
            if(!item.id) {
                item.id = generateUUID();
            }
        })
        states.jsonData = jsonData;

        console.log(constVars.prevZoom, states.zoom)
        if(canvas) {
            if(constVars.prevZoom === states.zoom)  {
                return;
            }
            // const currentZoom = canvas.getZoom();
            // canvas.zoomToPoint({ x: canvas.getWidth() / 2, y: canvas.getHeight() / 2 }, currentZoom * states.zoom);
            // canvas.renderAll();
            canvas.setDimensions({ width: states.realScreen.width, height: states.realScreen.height });
            canvas.setZoom(states.zoom);
            canvas.renderAll();
            return;
        }
        canvas = new fabric.Canvas('myCanvas', {
            width: states.realScreen.width,
            height: states.realScreen.height
        });
        console.log(states.realScreen.width, states.realScreen.height);
        renderCanvas(() => {
            canvas.setZoom(states.zoom);
            // const currentZoom = canvas.getZoom();
            // canvas.zoomToPoint({ x: canvas.getWidth() / 2, y: canvas.getHeight() / 2 }, currentZoom * 1.1);
 
        })
    })

    const handleAnimationFinish = useMemoizedFn(({
        height,
        open
    }) => {
        states.footerHeight = height;
        states.isOpenDrawer = open;
    })

    const handleUpload = useMemoizedFn((imgData, obj) => {
        const objects = canvas.getObjects();

        objects.forEach(item => {
            if(obj.id === item.get("id")) {
                // item.scaleToWidth(300);
                item.setSrc(imgData.src, () => {
                    console.log(imgData);
                    let _width = imgData.width > 300 ? 300 : imgData.width;
                    let _height = _width / (imgData.width / imgData.height);

                    item.set({
                        // width: _width,
                        // height: _height,
                        width: imgData.width,
                        height: imgData.height,
                        scaleX: _width / imgData.width,
                        scaleY: _height / imgData.height,
                    })
                    canvas.setActiveObject(item)
                    canvas.renderAll();
                });

            }
        })

        canvas.renderAll();

    })

    const renderCanvas = (renderCallback) => {
        canvas.clear();
        
        canvas.loadFromJSON(JSON.stringify(states.jsonData), () => {
            renderCallback?.();
            canvas.renderAll();

        });
    }

    const modalVariants = {
        visible: { opacity: 1, y: 0 },
        hidden: { opacity: 0, y: 30 }
    }

    return (
        <div style={{ width: '100%', height: '100vh', overflow: 'hidden' }}>
            <motion.div animate={{ ...states.realScreen }} style={{ position: 'relative', overflow: 'hidden' }}>
                <canvas id="myCanvas" />
            </motion.div>
            <DrawerBox
                onAnimateFinish={
                    handleAnimationFinish
                }
            >
                <div style={{ height: 40 }}></div>
                <AnimatePresence>
                    {
                        states.isOpenDrawer &&  states.jsonData?.objects?.map((object, index) => {

                            return (
                                <motion.div 
                                    key={object.id}
                                    style={{ display: 'inline-block'}}
                                    variants={modalVariants} 
                                    initial="hidden" 
                                    animate="visible" 
                                    exit="hidden"
                                    transition={{ duration: 0.3, ease: "easeInOut", delay: index * 0.05 }}
                                >
                                    <UploadBox 
                                        data={object}
                                        onLoaded={(imgData) => handleUpload(imgData, object)}
                                    />
                                </motion.div>

                                
                            )
                        })
                    }
                </AnimatePresence>
            </DrawerBox>

        </div>
    )
}


export default CanvasBox;